#include <iostream>
#include <memory>
#include <string>
#include "SmartPtr.hpp"
using namespace std;

int div(){
    int a, b;
    cin >> a >> b;
    if (b == 0){
        throw invalid_argument("除0错误");
    }
    return a / b;
}

void f1(){
    pair<string, string> *p1 = new pair<string, string>;
    pair<string, string> *p2 = new pair<string, string>;
    try
    {
        div();
    }
    catch(...){
        delete p1;
        cout << "delete: " << p1 << endl;
        throw;
    }

    delete p1;
    cout << "delete: " << p1 << endl;
}

void f2(){
    MySmartPtr::SmartPtr<pair<string, string>> p1(new pair<string, string>("aaa", "111"));
    MySmartPtr::SmartPtr<pair<string, string>> p2(new pair<string, string>("bbb", "222"));

    div();
}




struct ListNode{
    ListNode()
    {}

    ~ListNode(){
        cout << "~ListNode()" << endl;
    }

    int _data;
    // shared_ptr<ListNode> _next;
    // shared_ptr<ListNode> _prev;
    // weak_ptr<ListNode> _next;
    // weak_ptr<ListNode> _prev;
    // MySmartPtr::shared_ptr<ListNode> _next;
    // MySmartPtr::shared_ptr<ListNode> _prev;
    MySmartPtr::weak_ptr<ListNode> _next;
    MySmartPtr::weak_ptr<ListNode> _prev;
};

// int main(){
//     // try{
//     //     f2();
//     // }
//     // catch(const exception& e){
//     //     cout << e.what() << endl;
//     // }


//     // MySmartPtr::SmartPtr<pair<string, string>> p1(new pair<string, string>("aaa", "111"));
//     // MySmartPtr::SmartPtr<pair<string, string>> p2(new pair<string, string>("bbb", "222"));

//     // cout << ((*p1).first) << " " << ((*p1).second) << endl;
//     // cout << (p2->first) << " " << (p2->second) << endl;

//     // MySmartPtr::SmartPtr<pair<string, string>> p3(p1);

//     // auto_ptr<string> a1(new string("hello"));
//     // auto_ptr<string> a2(a1);        // 移交管理权，a1已经置为nullptr
//     // cout << a1->size() << endl;    // 错误使用


//     // unique_ptr<string> u1(new string("hello"));
//     // //unique_ptr<string> u2(u1);
//     // unique_ptr<string> u3(move(u1));
//     // //cout << (*u3) << endl;

//     // shared_ptr<string> s1(new string("hello"));
//     // shared_ptr<string> s2(s1);
//     // cout << (*s1) << " " << s1 << endl;
//     // cout << (*s2) << " " << s2 << endl;

//     // MySmartPtr::auto_ptr<string> a1(new string("hello"));
//     // cout << (*a1) << " " << (&(*a1)) << endl;
//     // MySmartPtr::auto_ptr<string> a2(a1);
//     // cout << (*a2) << " " << (&(*a2)) << endl;

//     // MySmartPtr::unique_ptr<string> u1(new string("hello"));
//     // cout << (*u1) << " " << (&(*u1)) << endl;
//     // MySmartPtr::unique_ptr<string> u2(move(u1));    // 移动拷贝
//     // cout << (*u2) << " " << (&(*u2)) << endl;
//     // MySmartPtr::unique_ptr<string> u3(new string);
//     // u3 = move(u2);                                  // 移动赋值
//     // cout << (*u3) << " " << (&(*u3)) << endl;
//     // u3 = move(u3);                                  // 自赋值
//     // cout << (*u3) << " " << (&(*u3)) << endl;

//     // MySmartPtr::shared_ptr<string> s1(new string("hello"));
//     // cout << (*(s1._ptr)) << " " << (s1._ptr) << " " << (*(s1._count)) << endl;
//     // MySmartPtr::shared_ptr<string> s2(s1);                                          // 拷贝构造
//     // cout << (*(s2._ptr)) << " " << (s2._ptr) << " " << (*(s2._count)) << endl;
//     // MySmartPtr::shared_ptr<string> s3(new string);
//     // s3 = s2;                                                                        // 拷贝赋值
//     // cout << (*(s3._ptr)) << " " << (s3._ptr) << " " << (*(s3._count)) << endl;
//     // s3 = s3;                                                                        // 自赋值
//     // cout << (*(s3._ptr)) << " " << (s3._ptr) << " " << (*(s3._count)) << endl;

//     MySmartPtr::shared_ptr<ListNode> node1(new ListNode);
//     MySmartPtr::shared_ptr<ListNode> node2(new ListNode);
//     cout << node1.use_count() << endl;
//     cout << node2.use_count() << endl;
//     node1->_next = node2;
//     node2->_prev = node1;
//     cout << node1.use_count() << endl;
//     cout << node2.use_count() << endl;
//     return 0;
// }


// 定制删除器
void file_delete(FILE *fp){
    if(fp){
        cout << "file delete: " << fp << endl;
        fclose(fp);
    }
}

struct ArrayDelete{
    void operator()(int *p){
        if(p){
            cout << "array_delete" << endl;
            delete[] p;
        }
    }
};
int main()
{
    MySmartPtr::shared_ptr<int> array_ptr(new int[100], ArrayDelete());
    MySmartPtr::shared_ptr<string> s1(new string("hello"));
    MySmartPtr::shared_ptr<string> s2(s1);
    return 0;
}